import { api, postApi } from '@/api';
import apiConfig from '@/api/config';
import TButton, { DelButton } from '@/components/TButton';
import ToolBar from '@/components/Toolbar';
import { API_RESULT } from '@/const';
import { getLocal, saveLocal } from '@/utils';
import { DatePicker, Form, Input, message, Modal } from 'antd';
import moment from 'moment';
import { useEffect, useMemo, useState } from 'react';
import TimelineItem from './components/TimelineComponent';
import './index.less';

export type TimePointT = {
  id: string | number;
  title: string;
  desc: string;
  datetime: moment.Moment;
};

const TIMELINE_RANGE_LOCAL_KEY = 'todo-timeline-range';

const defaultRange = getLocal(TIMELINE_RANGE_LOCAL_KEY, []).map((i: any) =>
  moment(i),
);

const Timeline = () => {
  const [data, setData] = useState<TimePointT[]>([]);

  const [show, setShow] = useState(false);
  const [edit, setEdit] = useState(false); // false即创建，true即编辑
  const [activeTarget, setActiveTarget] = useState<TimePointT | null>(null);

  const [range, setRange] = useState<any>(defaultRange);

  const processedData = useMemo(() => {
    if (!range.length) {
      return data;
    }
    return data.filter(
      (i) =>
        i.datetime.isSameOrAfter(range[0]) &&
        i.datetime.isSameOrBefore(range[1]),
    );
  }, [data, range]);

  useEffect(() => {
    getData();
  }, []);

  const getData = () => {
    api(apiConfig.getTimePoint.url)
      .then((res) => {
        if (res.code === API_RESULT.SUCCESS) {
          const list = res.data.map((i: TimePointT) => {
            i.datetime = moment(i.datetime);
            return i;
          }) as TimePointT[];
          list.sort((a: TimePointT, b: TimePointT) => {
            return a.datetime.diff(b.datetime);
          });
          setData(list);
          setActiveTarget(list?.[0] || null);
        } else {
          setData([]);
        }
      })
      .catch((e) => {
        setData([]);
        message.error('获取失败');
      });
  };

  const handleConfirm = (v: any) => {
    if (!edit) {
      const newItem = Object.assign({}, v, {
        id: Date.now().toString(),
        desc: v?.desc || '',
      }) as TimePointT;
      postApi(apiConfig.createTimePoint.url, newItem)
        .then((res) => {
          if (res.code === API_RESULT.SUCCESS) {
            getData();
            setShow(false);
            message.success('创建成功！');
          } else {
            message.error('创建失败');
          }
        })
        .catch((e) => {
          message.error('创建失败');
        });
    } else {
      const modifiedTarget = Object.assign({}, activeTarget, v) as TimePointT;
      handleUpdate(modifiedTarget);
    }
    setActiveTarget(null);
  };

  const handleEdit = (item: TimePointT) => {
    setActiveTarget(item);
    setShow(true);
    setEdit(true);
  };

  const handleUpdate = (item: TimePointT) => {
    postApi(apiConfig.updateTimePoint.url, item)
      .then((res) => {
        if (res.code === API_RESULT.SUCCESS) {
          getData();
          setShow(false);
          message.success('已更新');
        } else {
          message.error('更新失败');
        }
      })
      .catch((e) => {
        message.error('更新失败');
      });
  };

  const handleRemove = (target: TimePointT) => {
    postApi(apiConfig.removeTimePoint.url, target)
      .then((res) => {
        if (res.code === API_RESULT.SUCCESS) {
          getData();
          message.success('已删除');
        } else {
          message.error('删除失败');
        }
      })
      .catch((e) => {
        message.error('删除失败');
      });
  };

  const renderForm = () => {
    const config = [
      {
        field: 'title',
        label: '时间点名称',
        required: true,
      },
      {
        field: 'desc',
        label: '描述',
      },
      {
        field: 'datetime',
        label: '时间',
        component: () => (
          <DatePicker
            placeholder="选择时间点"
            size="small"
            style={{ width: '100%' }}
          />
        ),
        required: true,
      },
    ];

    return (
      <Form
        name="basic"
        initialValues={edit ? activeTarget || {} : {}}
        onFinish={handleConfirm}
        autoComplete="off"
        style={{ marginTop: '20px' }}
        layout="vertical"
      >
        {config.map((i) => (
          <Form.Item
            label={i.label}
            name={i.field}
            rules={[{ required: i.required || false }]}
            key={i.field}
          >
            {i.component ? (
              i.component()
            ) : (
              <Input autoComplete="off" size="small" />
            )}
          </Form.Item>
        ))}
        <Form.Item>
          <TButton submit fullWidth>
            确定
          </TButton>
        </Form.Item>
      </Form>
    );
  };

  const renderItem = (item: TimePointT) => {
    const isToday = item.datetime.isSame(moment(), 'day');

    const getDiffDays = (m: moment.Moment) => {
      const days = m.diff(moment(), 'days');
      return days > 0 ? `${days}天后` : `${-days}天前`;
    };
    return (
      <div
        className={
          isToday
            ? 'time-item__content--today time-item__content'
            : 'time-item__content'
        }
        onClick={() => handleEdit(item)}
      >
        <div className="time-item__info">
          <div className="time-item__title">{item.title}</div>

          <div className="time-item__desc">{item.desc}</div>
        </div>
        <div
          className={
            isToday
              ? 'time-item__flag--today time-item__flag'
              : 'time-item__flag'
          }
        >
          <span title={getDiffDays(item.datetime)}>
            {isToday ? '今天' : item.datetime.fromNow()}
          </span>
          <DelButton onRemove={() => handleRemove(item)} />
        </div>
      </div>
    );
  };

  return (
    <>
      <ToolBar
        leftActions={
          <TButton
            onClick={() => {
              setActiveTarget(null);
              setEdit(false);
              setShow(true);
            }}
            style={{ width: '230px', height: '30px' }}
          >
            新建
          </TButton>
        }
        rightActions={
          <>
            <div className="container" style={{ margin: '0 20px' }}>
              <label style={{ marginRight: '20px' }}>范围</label>
              <DatePicker.RangePicker
                size="small"
                value={range}
                onChange={(dates) => {
                  const range =
                    dates?.map((i) => {
                      return moment(i?.toISOString());
                    }) || [];
                  setRange(range);
                  saveLocal(
                    TIMELINE_RANGE_LOCAL_KEY,
                    range.map((i) => i.toISOString()),
                  );
                }}
              />
            </div>
            <TButton
              plain
              onClick={() => {
                setRange([moment(), moment('2082-06-11T09:01:47.515Z')]);
              }}
              style={{ margin: '0 20px' }}
            >
              今天起
            </TButton>
            <TButton
              plain
              onClick={() => {
                setRange([moment('1800-06-11T09:01:47.515Z'), moment()]);
              }}
            >
              今天前
            </TButton>
          </>
        }
      />
      <div className="content-area col-flex-container scroll">
        <div className="time-line__main">
          {processedData.map((i, index) => {
            return (
              <TimelineItem
                title={
                  <div className="time-item__pre">
                    {i.datetime.format('Y/M/D')}
                  </div>
                }
                content={renderItem(i)}
                key={i.id}
                isFirst={index === 0}
                isLast={index === processedData.length - 1}
                onEdit={() => handleEdit(i)}
                height={'100px'}
              />
            );
          })}
        </div>
      </div>

      <Modal
        visible={show}
        onCancel={() => setShow(false)}
        footer={false}
        destroyOnClose
      >
        {renderForm()}
      </Modal>
    </>
  );
};

export default Timeline;
